package com.sky.service.rider.impl;

import com.sky.dto.CourierTradeQueryDto;
import com.sky.mapper.common.ShortUrlMapper;
import com.sky.mapper.courier.CourierMapper;
import com.sky.mapper.courier.CourierTradeOrderMapper;
import com.sky.mapper.user.OrderDetailMapper;
import com.sky.mapper.user.OrderMapper;
import com.sky.pojo.*;
import com.sky.result.Result;
import com.sky.service.rider.CourierTradeOrderService;
import com.sky.vo.CourierTradeOrderVO;
import com.sky.vo.OrderDetailVO;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.geo.Distance;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.Duration;
import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;

@Service
public class CourierTradeOrderServiceImpl implements CourierTradeOrderService {


    @Autowired
    private CourierTradeOrderMapper courierTradeOrderMapper;

    @Autowired
    private CourierMapper courierMapper;

    @Autowired
    private RedisTemplate redisTemplate;


    @Autowired
    private OrderDetailMapper orderDetailMapper;

    @Autowired
    private ShortUrlMapper shortUrlMapper;

    @Autowired
    private OrderMapper orderMapper;

//    @Override
//    public Result<List> queryPendingOrders(Integer status, Long courierId) {
//
//        List<CourierTradeOrderVO> list = new ArrayList<>();
//
//        //查询数据库骑手的待接单信息
//        List<CourierTradeOrder> courierTradeOrderList = courierTradeOrderMapper.selectOrdersByStatusAndCourierId(status,courierId);
//
//        Courier courier = courierMapper.selectById(courierId);
//
//        //计算运单的相关数据
//        courierTradeOrderList.forEach(tradeOrder -> {
//            CourierTradeOrderVO vo = new CourierTradeOrderVO();
//            //属性填充
//            BeanUtils.copyProperties(tradeOrder,vo);
//
//
//            //计算商家和快递员的距离
//            String merchantLngLat = MapUtils.addressToLnglat(tradeOrder.getShopAddress());
//            double merchantCourierDistance = MapUtils.calculateDistance2(courier.getCurLocation(), merchantLngLat);
//            vo.setShopAndCourierDistance(merchantCourierDistance);
//            //商家和客户的距离
//            String customerLngLat = MapUtils.addressToLnglat(vo.getCustomerAddress());
//            double merchantCustomerDistance = MapUtils.calculateDistance2(customerLngLat, merchantLngLat);
//            vo.setShopAndCustomerDistance(merchantCustomerDistance);
//            //客户期望送达时间和当前时间差
//            Duration between = Duration.between(LocalDateTime.now(), vo.getCustomerExpectedDeliveryTime());
//            long l = between.get(ChronoUnit.SECONDS);
//            vo.setCurrentTimeAndCustomerExpectedTime(l);
//
//            list.add(vo);
//        });
//
//
//
//        AtomicInteger sort = new AtomicInteger(1);
//        //序号，商家和客户的距离排序，添加序号
//        List<CourierTradeOrderVO> res = list.stream().sorted(Comparator.comparing(CourierTradeOrderVO::getShopAndCustomerDistance))
//                .map(vo->{
//                    vo.setMarkSort(sort.getAndIncrement());
//                    return  vo;
//                }).collect(Collectors.toList());
//
//        return Result.success(res);
//    }


    //距离的计算通过redis来进行优化
    /*
        1.首先应该将 商家、骑手、客户地址对应的经纬度全部放到redis中去
        2.然后我们就可以计算
     */
    @Override
    public Result<List<CourierTradeOrderVO>> queryPendingOrders(Integer status, Long courierId) {

        List<CourierTradeOrderVO> list = new ArrayList<>();

        //查询数据库骑手的待接单信息
        List<CourierTradeOrder> courierTradeOrderList = courierTradeOrderMapper.selectOrdersByStatusAndCourierId(status,courierId);

        Courier courier = courierMapper.selectById(courierId);

        //计算运单的相关数据
        courierTradeOrderList.forEach(tradeOrder -> {
            CourierTradeOrderVO vo = new CourierTradeOrderVO();
            //属性填充
            BeanUtils.copyProperties(tradeOrder,vo);


            //计算商家和快递员的距离
            String merchantLocationKey = "merchant_"+1;
            String courierLocationKey = "courier_"+courierId;
            Distance location = redisTemplate.opsForGeo().distance("location", merchantLocationKey, courierLocationKey);
            vo.setShopAndCourierDistance( location.getValue());
            //商家和客户的距离
            String customerLocationKey = "customer_"+1;
            Distance location2 = redisTemplate.opsForGeo().distance("location", merchantLocationKey, customerLocationKey);
            vo.setShopAndCustomerDistance(location2.getValue());
            //客户期望送达时间和当前时间差
            Duration between = Duration.between(LocalDateTime.now(), vo.getCustomerExpectedDeliveryTime());
            long l = between.get(ChronoUnit.SECONDS);
            vo.setCurrentTimeAndCustomerExpectedTime(l);

            list.add(vo);
        });



        AtomicInteger sort = new AtomicInteger(1);
        //序号，商家和客户的距离排序，添加序号
        List<CourierTradeOrderVO> res = list.stream().sorted(Comparator.comparing(CourierTradeOrderVO::getShopAndCustomerDistance))
                .map(vo->{
                    vo.setMarkSort(sort.getAndIncrement());
                    return  vo;
                }).collect(Collectors.toList());

        return Result.success(res);
    }

    @Override
    public Result<CourierTradeOrder> queryTradeOrderByTradeNo(String tradeNo) {
        CourierTradeOrder courierTradeOrder = courierTradeOrderMapper.selectByOrderNumber(tradeNo);
        return Result.success(courierTradeOrder);

    }


    @Override
    @Transactional
    public Result confirmOrComplete(Long tradeNo, Integer status) {


        if(status==CourierTradeOrder.CONFIRM_TRADE){
            //确认取货
            //修改订单和运单状态即可
            courierTradeOrderMapper.updateStatusByTradeNo(tradeNo,status);
            CourierTradeOrder tradeOrder = courierTradeOrderMapper.selectByTradeNo(tradeNo);
            orderMapper.updateOrderStatusByNumber(tradeOrder.getOrderNumber(), Orders.TOBEDELIVERED);
        }else if(status==CourierTradeOrder.TRADE_COMPLETE){
            //确认送达
            //运单更新状态和完成时间
            courierTradeOrderMapper.updateStatusAndCompleteTimeByTradeNo(status,LocalDateTime.now(),tradeNo);

            //订单更新状态和送达时间
            CourierTradeOrder tradeOrder = courierTradeOrderMapper.selectByTradeNo(tradeNo);
            orderMapper.updateStatusAndDeliveryTimeByNumber(Orders.COMPLETE_ORDER,LocalDateTime.now(),tradeOrder.getOrderNumber());

            //bitmap的位置为0
            ShortUrl shortUrl = shortUrlMapper.selectByTradeNo(tradeNo);
            int hashCode = shortUrl.getShortCode().hashCode();
            long index = 0l;
            if(hashCode<0){
                index = Math.abs(hashCode)+2147483648l;
            }else{
                index = hashCode;
            }
            redisTemplate.opsForValue().setBit("short_code",index,false);

        }


        return Result.success();
    }

    @Override
    public Result<List<OrderDetailVO>> confirmPickUpList(Long tradeNo) {

        List<OrderDetailVO> voList = new ArrayList<>();

        List<OrderDetail> details = orderDetailMapper.selectByTradeNo(tradeNo);
        details.forEach(orderDetail -> {
            OrderDetailVO vo = new OrderDetailVO();
            vo.setNumber(orderDetail.getNumber());
            vo.setName(orderDetail.getName());
            voList.add(vo);
        });


        return Result.success(voList);
    }

    @Override
    public Result<List<CourierTradeOrderVO>> queryWaybillsByDate(CourierTradeQueryDto dto) {
        //查询骑手当天的订单数据 （已送达和已取消）
        List<CourierTradeOrder> courierTradeOrders =  courierTradeOrderMapper.selectCourierOrders(dto.getDate(),dto.getStatus(),dto.getCourierId());
        List<CourierTradeOrderVO> voList = new ArrayList<>();
        courierTradeOrders.forEach(tradeOrder -> {
            CourierTradeOrderVO vo = new CourierTradeOrderVO();
            BeanUtils.copyProperties(tradeOrder,vo);
            //计算商家和骑手的距离
            vo.setShopAndCourierDistance(233.00);
            //计算商家和客户的距离
            vo.setShopAndCustomerDistance(400.00);
            //计算时间差
            vo.setCurrentTimeAndCustomerExpectedTime(6555l);
            vo.setMarkSort(1);
            voList.add(vo);
        });
        return Result.success(voList);
    }
}
